<?php
if (!defined('SHARE_VERSION')) exit('No direct script access allowed');
/**
 +----------------------------------------------------------
 * Copyright (C) 2008-2010	itye.cn
 +----------------------------------------------------------
 * 文件名：Template.class.php
 * 说明：模板类,深度整体框架
 +----------------------------------------------------------
 * 程序员：吴锋
 * QQ:7462679
 * Email:7462679@qq.com
 +----------------------------------------------------------
 * 最后更新时间：2012-4
 +----------------------------------------------------------
 */

class Template
{
	public $templateDir      = '';	// 模板路径
	public $templateCompiled = '';	// 模板编译路径
	public $var_regexp       = "\@?\\\$[a-zA-Z_][\\\$\w]*(?:\[[\w\-\.\"\'\[\]\$]+\])*";
	public $vtag_regexp      = "\<\?php echo (\@?\\\$[a-zA-Z_][\\\$\w]*(?:\[[\w\-\.\"\'\[\]\$]+\])*)\;\?\>";
	public $const_regexp     = "\{([\w]+)\}";
	
	public function __construct()
	{
		 header('Content-type: text/html; charset=utf-8');
	}
	
	/**
	 +----------------------------------------------------------
	 * complie 读模板页进行替换后写入到cache页里
	 +----------------------------------------------------------
	 * @access public
	 +----------------------------------------------------------
	 * @param string $tplFile ：模板源文件地址
	 * @param string $objFile ：模板cache文件地址
	 +----------------------------------------------------------
	 * @return string
	 +----------------------------------------------------------
	 */
	public function complie($tplFile='', $objFile='')
	{
		$template = file_get_contents($tplFile);
		$template = $this->parse($template);
		$fp = fopen($objFile, 'w');
		fwrite($fp, $template);
		fclose($fp);
	}
	
	/**
	 +----------------------------------------------------------
	 * parse 解析模板标签
	 +----------------------------------------------------------
	 * @access private
	 +----------------------------------------------------------
	 * @param string $template ：模板源文件内容
	 +----------------------------------------------------------
	 * @return string
	 +----------------------------------------------------------
	 */
	private function parse($template)
	{
		$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);//去除html注释符号<!---->
		$template = preg_replace("/\{($this->var_regexp)\}/", "<?php echo \\1;?>", $template);//替换带{}的变量
		$template = preg_replace("/\{($this->const_regexp)\}/", "<?php echo \\1;?>", $template);//替换带{}的常量
		$template = preg_replace("/(?<!\<\?php echo |\\\\)$this->var_regexp/", "<?php echo \\0;?>", $template);//替换重复的<?php echo
		$template = preg_replace("/\{php (.*?)\}/ies", "\$this->stripvtag('<?php \\1?>')", $template);//替换php标签
		$template = preg_replace("/\{for (.*?)\}/ies", "\$this->stripvtag('<?php for(\\1) {?>')", $template);//替换for标签
		$template = preg_replace("/\{elseif\s+(.+?)\}/ies", "\$this->stripvtag('<?php } elseif (\\1) { ?>')", $template);//替换elseif标签
		for($i=0; $i<3; $i++) {
			$template = preg_replace("/\{loop\s+$this->vtag_regexp\s+$this->vtag_regexp\s+$this->vtag_regexp\}(.+?)\{\/loop\}/ies", "\$this->loopSection('\\1', '\\2', '\\3', '\\4')", $template);
			$template = preg_replace("/\{loop\s+$this->vtag_regexp\s+$this->vtag_regexp\}(.+?)\{\/loop\}/ies", "\$this->loopSection('\\1', '', '\\2', '\\3')", $template);
		}
		$template = preg_replace("/\{if\s+(.+?)\}/ies", "\$this->stripvtag('<?php if(\\1) { ?>')", $template);//替换if标签
		$template = preg_replace("/\{include\s+(.*?)\}/is", "<?php include \\1; ?>", $template);//替换include标签
		$template = preg_replace("/\{template\s+(\w+?)\}/is", "<?php include \$this->display('\\1.html'); ?>", $template);//替换template标签
		$template = preg_replace("/\{function\s+(.*?)\}/is", "<?php \\1(); ?>", $template); // 替换function
		$template = preg_replace("/\{else\}/is", "<?php } else { ?>", $template);//替换else标签
		$template = preg_replace("/\{\/if\}/is", "<?php } ?>", $template);//替换/if标签
		$template = preg_replace("/\{\/for\}/is", "<?php } ?>", $template);//替换/for标签
		$template = preg_replace("/$this->const_regexp/", "<?php echo \\1;?>", $template);//note {else} 也符合常量格式，此处要注意先后顺??
		$template = preg_replace("/(\\\$[a-zA-Z_]\w+\[)([a-zA-Z_]\w+)\]/i", "\\1'\\2']", $template);//将二维数组替换成带单引号的标准模式		
		$template = preg_replace("/\{U(.*?)\}/ies", "\$this->stripvtag('<?php U\\1;?>')", $template);	// 模板U函数
		$template = preg_replace("/\{:U(.*?)\}/ies", "\$this->stripvtag('<?php echo U\\1;?>')", $template);	// 模板U函数
		$template = preg_replace("/\{lang.(.*?)}/ies", "\$this->stripvtag('<?php echo \$this->lang[\'\\1\'];?>')", $template);
		$template = "<? if(!defined('SHARE_VERSION')) exit('Access Denied');?>\r\n$template";
		return $template;
	}
	
	/**
	 +----------------------------------------------------------
	 * stripvTag 正则表达式匹配替换
	 +----------------------------------------------------------
	 * @access private
	 +----------------------------------------------------------
	 * @param string $s ：模板内容
	 +----------------------------------------------------------
	 * @return string
	 +----------------------------------------------------------
	 */
	private function stripvTag($s)
	{
		return preg_replace("/$this->vtag_regexp/is", "\\1", str_replace("\\\"", '"', $s));
	}
	
	/**
	 +----------------------------------------------------------
	 * loopSection 替换模板中的LOOP循环
	 +----------------------------------------------------------
	 * @access private
	 +----------------------------------------------------------
	 * @param string $arr ：
	 * @param string $k
	 * @param string $v
	 * @param string $statement
	 +----------------------------------------------------------
	 * @return string
	 +----------------------------------------------------------
	 */
	private function loopSection($arr, $k, $v, $statement)
	{
		$arr = $this->stripvTag($arr);
		$k = $this->stripvTag($k);
		$v = $this->stripvTag($v);
		$statement = str_replace("\\\"", '"', $statement);
		return $k ? "<?php foreach((array)$arr as $k=>$v) {?>$statement<?php }?>" : "<?php foreach((array)$arr as $v) {?>$statement<?php } ?>";
	}
	
	/**
	 +----------------------------------------------------------
	 * display 加载模板
	 +----------------------------------------------------------
	 * @access public
	 +----------------------------------------------------------
	 * @param string $tplfile 模板文件路径
	 +----------------------------------------------------------
	 * @return string
	 +----------------------------------------------------------
	 */
	public function display($templateFile='')
	{
		$templateFile	= trim(strtolower($templateFile));
		if ( empty($templateFile) ){
			return;
		}
		$templateFile 	= $this->templateDir.'/'.$templateFile;
		$compileFile      = $this->templateCompiled.'/'.md5(strtolower($templateFile)).'.php';

		if ( !file_exists($templateFile) ) {
			$this->_error('模板文件不存在','模板文件'.$templateFile.'不存在！');
		}
		if(@filemtime($templateFile) > @filemtime($compileFile)) {
			// 加载模板文件
			$this->complie($templateFile, $compileFile);
		}
		return $compileFile;
	}
	// 错误提示
	private function _error($title,$msg){
		showError($title, $msg);
	}
}
?>